/*
    组件之间的通信 
    
    1. 父子 组件 
    <A>
        <B></B>
    </A>
    2. 兄弟组件 
    <A></A>
    <B></B>

    props 传递数据
    state 修改数据 

    子组件如何修改父组件
    1. 反向 props  父组件把修改自身变量state的方法 通过 props 传递给子组件 子组件触发 

    
    兄弟组件通信
    1. 中间人模式  子组件A 去修改父组件  父组件再去修改 组件B 
    a. 子改父   反向props  + props
    b. 子改父   反向props  + ref 


    2. 事件机制  bus 事件总线  event (emit on once)
    emit 发送事件
    on 监听事件
    once 监听一次
    remove 移除事件


    架构
    flux  redux mobx  event 


    受控的Input 组件
    受控的组件  input 绑定动态的 value  value 受state 状态控制的  只有state改变 input才能改变
    非受控的组件  value 没有绑定状态 


*/ 

import React, { Component } from 'react'

import EventEmitter from 'events'  //Node自带的API


const bus = new EventEmitter()    //事件总线

export default class Props2 extends Component {

    state={
        count:10000,
        word:"wh2114daydayup",
        show:true
    }
    changecount=()=>{
        this.setState({
      count:++this.state.count
  })
      }

      changeword=word=>{
          this.setState({
              word
          })
      }
      changeshow=show=>{
        this.setState({
            show
        })
    }
    changeTwoByRefs=()=>{
        this.two.setState({
            msg:"一天十套面试题.....",
            flag:true
        })
        this.two.changeflag()
    }
  render() {
      const {count,word,show,changeshow} =this.state
 
     
    return (  
      <div>
   {/* <h2> react 父子组件通信</h2> 
   <h2> react  子组件修改父组件 </h2>
   <h2> count--{count}</h2>
   <h2> word--{word}</h2>
   <p style={{width:200,height:200,backgroundColor:"pink",display:show?'block':'none'}}>
                我是被子组件控制的
            </p> */}
   <hr/>
    <ChildOne
    changecount={this.changecount}
    changeword={this.changeword}
    show={show}
    changeshow={this.changeshow}
    ref={el=>this.one=el}
    changeTwoByRefs={this.changeTwoByRefs}
    />
  <hr/>
   <ChildTwo
   count={count}
   word={word}
   ref={el=>this.two=el}
   />

     </div>



    )
  }
}

class ChildOne extends Component{
    changeTwodata=()=>{
        bus.emit("changeTwodata","wh2114----")
    }
    render(){
        const {changecount,changeword,show,changeshow,changeTwoByRefs}=this.props
        return(
            <div>
            <h2> 
                childone --one  -one 
            </h2>
            <button onClick={changecount}>通过反向props 实现子改父</button>
            <p>
                <input type="text" ref={el=>this.inp=el}  onChange={()=>changeword(this.inp.value)}/>
            </p>
          <button onClick={()=>changeshow(!show)}>{show?'隐藏':'显示'}</button>
          <button onClick={changeTwoByRefs}>通过REF实现兄弟组件通信</button>
          <button onClick={this.changeTwodata}>通过事件总线直接修改two组件的flag</button>
        </div>
        )
       
    }
}

const arr=['1234','abcd','qwer','poiu']

class ChildTwo extends Component{
    state={
        msg:"wh2114-用力背面试题"
    }
    changeflag(){
        this.setState({
            flag:!this.state.flag
        })
    }
    //monted
    componentDidMount(){
     bus.on("changeTwodata",msg=>{
    this.setState({
        msg
    })
    this.changeflag()
})
    }
    render(){

        return(
            <div>
           {
               this.state.flag && <div>
                    <h2>
                childtwo --two  -two 
            </h2>
            <h2>
               count==={this.props.count}
            </h2>
            <h2>
             word==={this.props.word}
            </h2>
            <h2>
               msg==={this.state.msg}
            </h2>
               </div>
               
           }
            <MyList id="ones" num ={1234}>
                {arr}
            </MyList>
        </div>
        )
       
    }
}

 class MyList extends Component{

    render(){
      console.log(this);
        return(
      <div>
          <h2>MyList-MyList-MyList</h2>
          {
              this.props.children.map((l,i)=>{
                  return(
                      <p key={i}> {l}</p>
                  )
              })
          }
          <MyDemo>
              <h2>
                  vue数据双向绑定的底层原理
              </h2>
              <h2>
                 history pop 和push的区别
              </h2>
              <h2>
                 线程和进城的区别
              </h2>
          </MyDemo>
      </div>
        )
    }
}

class MyDemo extends Component{

    render(){
   
        return(
      <div>
          <h2>MyDemo</h2>
          {
              this.props.children
          }
         <MyRule>
        <h2>vue路由守卫</h2>
        <h2>vue源码</h2>

         </MyRule>
      </div>
        )
    }
}

const MyRule =({
    children,
    word
})=>{
    return(
        <div>
            <h2>
                我的规则
            </h2>
            <div>
                {children}
            </div>
            <div>
                {word}
            </div>
        </div>
    )
}
 
